package com.lez.coroutine02

import kotlinx.coroutines.*
import org.junit.Test
import java.lang.Exception
import java.lang.IllegalArgumentException
import kotlin.system.measureTimeMillis

//协程 launch和async 两个构建器返回值比较
class Coroutine01 {

    @Test
    fun `test coroutine build`() = runBlocking {
        val job1 = launch {
            delay(200)
            println("job1 finished.")
        }
        val job2 = async {
            delay(300)
            println("job2 finished.")
            "job2 result"
        }
        println(job2.await()) //通过await()可以获取到async

    }
    //用launch构建器 的join方法 可以使前边的协程执行完后，在执行后边的协程
    //用async构建器的 await()方法，可以使前边的协程执行完后，再执行后边的协程
    @Test
    fun `test coroutine join`() = runBlocking {
        val job1 = launch {
            delay(5000)
            println("One.")
        }
        job1.join()  //其他的协程先等着，等job1执行完后再执行其他的协程

        val job2 = launch {
            delay(200)
            println("Two.")
        }
        val job3 = launch {
            delay(200)
            println("Three.")
        }
    }

    @Test
    fun `test sync`() = runBlocking {
        val times = measureTimeMillis {
            val one = doOne()
            val two = doTwo()
            println("执行结果：${one + two}")
        }
        println("方法执行总时间${times}")
    }
    //async组合并发
    @Test
    fun `test combine sync`() = runBlocking {
        val times = measureTimeMillis {
            val one = async { doOne() }
            val two = async { doTwo() }
            println("执行结果：${one.await() + two.await()}")
        }
        println("方法执行总时间${times}")
    }

    private suspend fun doOne(): Int{
        delay(1000)
        return 15
    }
    private suspend fun doTwo(): Int{
        delay(1000)
        return 24
    }
    //作用域构建器,coroutineScope内的函数都执行完，作用域才会结束，如果有任一任务执行失败，整个作用域的任务都会取消
    @Test
    fun `test coroutine scope builder`() = runBlocking {
        coroutineScope {
            val job1 = async {
                delay(600)
                println("One------.")
                throw IllegalArgumentException()
            }
            val job2 = async {
                delay(200)
                println("Three------.")
                "dddd"
            }
            println(job2.await())
        }
    }
    //作用域构建器,supervisorScope内的函数都执行完，作用域才会结束，如果有任一任务执行失败,不影响其他任务
    @Test
    fun `test supervisor scope builder`() = runBlocking {
        supervisorScope {
            val job1 = launch {
                delay(600)
                println("One------.")
            }
            val job2 = launch {
                delay(200)
                println("Three------.")
                throw IllegalArgumentException()
            }
        }
    }
}